﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;
using System.Reflection;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using System.IO;

namespace ModelImporter
{
    public class ModelTestDesc
    {
        public struct Triangle
        {
            public Vector3 p0;
            public Vector3 p1;
            public Vector3 p2;
        };

        public Vector3 BoundsMin;
        public Vector3 BoundsMax;

        public Triangle[] Triangles;

        public MemoryStream TriMesh = null;
        public MemoryStream ConvexMesh = null;

        public ModelTestDesc()
        {
        }
    }

    [ContentTypeWriter]
    class ModelTestDescWriter : ContentTypeWriter<ModelTestDesc>
    {
        protected override void Write(ContentWriter output, ModelTestDesc value)
        {
            output.Write(value.BoundsMin);
            output.Write(value.BoundsMax);

            output.Write((value.Triangles != null) ? true : false);
            output.Write((value.TriMesh != null) ? true : false);
            output.Write((value.ConvexMesh != null) ? true : false);

            if (value.Triangles != null)
            {
                long length = value.Triangles.Length;
                output.Write(length);

                for (int i = 0; i < length; i++)
                {
                    ModelTestDesc.Triangle t = value.Triangles[i];
                    output.Write(t.p0);
                    output.Write(t.p1);
                    output.Write(t.p2);
                }
            }

            if (value.TriMesh != null)
            {
                long len = value.TriMesh.Length;
                output.Write(len);
                output.Write(value.TriMesh.GetBuffer());
            }

            if (value.ConvexMesh != null)
            {
                long len = value.ConvexMesh.Length;
                output.Write(len);
                output.Write(value.ConvexMesh.GetBuffer());
            }
        }
        public override string GetRuntimeType(TargetPlatform targetPlatform)
        {
            return typeof(ModelTestDesc).AssemblyQualifiedName;
        }
        public override string GetRuntimeReader(TargetPlatform targetPlatform)
        {
            return typeof(ModelTestDescReader).AssemblyQualifiedName;
        }
    }

    class ModelTestDescReader : ContentTypeReader<ModelTestDesc>
    {
        /// <summary>
        /// Loads an imported shader.
        /// </summary>
        protected override ModelTestDesc Read(ContentReader input, ModelTestDesc existingInstance)
        {
            ModelTestDesc desc = new ModelTestDesc();
            desc.BoundsMin = input.ReadVector3();
            desc.BoundsMax = input.ReadVector3();

            bool hasTriangles = input.ReadBoolean();
            bool hasTriMesh = input.ReadBoolean();
            bool hasConvexMesh = input.ReadBoolean();

            if (hasTriangles)
            {
                long length = input.ReadInt64();
                desc.Triangles = new ModelTestDesc.Triangle[length];
                for (int i = 0; i < length; i++)
                {
                    desc.Triangles[i].p0 = input.ReadVector3();
                    desc.Triangles[i].p1 = input.ReadVector3();
                    desc.Triangles[i].p2 = input.ReadVector3();
                }
            }

            if (hasTriMesh)
            {
                long triMeshCount = input.ReadInt64();
                byte[] triMeshBuffer = input.ReadBytes((int)triMeshCount);
                MemoryStream s = new MemoryStream(triMeshBuffer);
                desc.TriMesh = s;
            }

            if (hasConvexMesh)
            {
                long convexMeshCount = input.ReadInt64();
                byte[] convexMeshBuffer = input.ReadBytes((int)convexMeshCount);
                MemoryStream s = new MemoryStream(convexMeshBuffer);
                desc.ConvexMesh = s;
            }

            return desc;
        }
    }
}
